package cn.monkey.family.server.domain.uc.auth.wechat;

import cn.monkey.family.data.Result;
import cn.monkey.family.data.Results;
import cn.monkey.family.data.context.RequestContext;
import cn.monkey.family.data.uc.auth.Authorization;
import cn.monkey.family.data.uc.auth.wechat.WechatPhoneNoDecodeRequest;
import cn.monkey.family.data.uc.user.User;
import cn.monkey.family.data.uc.auth.wechat.WechatSignInRequest;
import cn.monkey.family.data.uc.auth.wechat.WechatUser;
import cn.monkey.family.server.domain.uc.auth.IAfterAuthorizeHandler;
import cn.monkey.family.server.domain.uc.user.UserRepository;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class WechatService implements IWechatService {
    final WechatClient wechatClient;
    final UserRepository userRepository;
    final IAfterAuthorizeHandler afterAuthorizeHandler;

    public WechatService(WechatClient wechatClient,
                         UserRepository userRepository,
                         IAfterAuthorizeHandler afterAuthorizeHandler) {
        this.wechatClient = wechatClient;
        this.userRepository = userRepository;
        this.afterAuthorizeHandler = afterAuthorizeHandler;
    }

    @Override
    public Result<Authorization> authorize(RequestContext requestContext, WechatSignInRequest authRequest) {
        String mobile = authRequest.getMobile();
        Optional<User> userOptional = this.userRepository.findOneByMobile(mobile);
        if (userOptional.isEmpty()) {
            return Results.fail("INVALID_MOBILE");
        }
        Result<WechatUser> wechatUserResult = this.wechatClient.findOneByCode(userOptional.get(),
                authRequest.getAppId(),
                authRequest.getCode());
        if (!Results.isOk(wechatUserResult)) {
            return Results.fromFailOrError(wechatUserResult);
        }
        return this.afterAuthorize(requestContext, userOptional.get());
    }

    @Override
    public Result<String> decodePhoneNo(RequestContext requestContext, WechatPhoneNoDecodeRequest request) {
        return null;
    }

    private Result<Authorization> afterAuthorize(RequestContext requestContext, User user) {
        return this.afterAuthorizeHandler.handle(requestContext, user);
    }
}
